/**
 * Copyright (c) [2025] [何屹林]
 *
 * 保留所有权利。
 *
 * 文件名称：NFA_maker.h
 * 模块功能说明：
 * 该模块定义NFA内部各种结构体，定义生成NFA过程的各种函数，并构建NFA状态转移表，完成了NFA图生成状态转换表的函数和NFA图的生成工作。
 *
 * 华南师范大学-计算机学院-网络工程-1班
 * 作者：何屹林-20222132023
 * 完成日期：2025年7月24日
 */
#ifndef NFA_MAKER_H
#define NFA_MAKER_H

#include "utils.h"
#include "presolve.h"


//声明nfa图的结点结构体
struct NFA;

//nfa图的边结构体
struct Edge{
    QChar c;//收到的符号
    NFA *next;//去到的下一个结点
};

//定义nfa图的结点结构体
struct NFA{
    int id=-1;
    int cd=0;//在到达终态并结束后获得的token对应的单词编码（默认0对应的是终结符$）
    bool isStart=false;
    bool isEnd=false;
    bool isExit =false;
    QVector<Edge> edges; //边的集合，一个结点可能有多条边
};

//NFA起点和终点，设置为同一个结构体便于识别是一个单一的NFA图
struct NFA_begin_end
{
    NFA*start;
    NFA*end;
    //构造函数，默认给空白，在生成图的时候再给定起始点
    NFA_begin_end(NFA*s=nullptr,NFA*e=nullptr):start(s),end(e){}
};

// 开辟过的NFA节点
extern QStack<NFA*> NFAs;

//两个NFA哈希表，把结点和id相对应，便于随时灵活调用
extern QHash<int,NFA*>NFAHash;
extern QHash<NFA*,int>NFAHash2;

// 最终的NFA，存一下头结点和尾结点即可
extern NFA_begin_end resultNFA;

// 状态转换表单个结点
struct NFAState {
    int id = -1; // 唯一id值
    QString flag;  // 标记初态还是终态
    QMap<QChar, QSet<int>> char2state;  // 对应字符能到达的状态
};

// 状态转换表
extern QMap<int, NFAState> StateTable;

// stateTable插入顺序记录，方便后续输出
extern QVector<int> InsertOrder;
extern QSet<int> StartNFA;
extern QSet<int> EndNFA;
extern QMap<int, int> ExitNFA;  // id映射cd

//记录退出态的最大编码
extern int maxcode;


#endif // NFA_MAKER_H
